package com.zzl.study.nacos.loadbalancer;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import com.zzl.study.nacos.NacosServiceInstance;
import org.springframework.cloud.client.ServiceInstance;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Nacos负载均衡组件
 *
 * @author: zhangzl
 * @date: 2025/7/16 16:27
 * @version: 1.0
 */
public class NacosBalancer extends Balancer {

    /**
     * ipv4正则
     */
    private static final String IPV4_REGEX = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";

    /**
     * ipv6元数据Key
     */
    private static final String IPV6_KEY = "IPv6";

    /**
     * 根据权重获取Nacos实例
     *
     * @param instances 实例列表
     * @return Nacos实例
     */
    public static Instance getHostByRandomWeight2(List<Instance> instances) {
        return getHostByRandomWeight(instances);
    }

    /**
     * 根据权重获取实例
     *
     * @param serviceInstances 实例列表
     * @return 实例
     */
    public static ServiceInstance getHostByRandomWeight3(List<ServiceInstance> serviceInstances) {
        Map<Instance, ServiceInstance> instanceMap = new HashMap<>();
        List<Instance> nacosInstance = serviceInstances.stream().map(serviceInstance -> {
            Map<String, String> metadata = serviceInstance.getMetadata();
            Instance instance = new Instance();
            instance.setIp(serviceInstance.getHost());
            instance.setPort(serviceInstance.getPort());
            instance.setWeight(Double.parseDouble(metadata.get("nacos.weight")));
            instance.setHealthy(Boolean.parseBoolean(metadata.get("nacos.healthy")));
            instanceMap.put(instance, serviceInstance);
            return instance;
        }).toList();
        Instance instance = getHostByRandomWeight2(nacosInstance);
        NacosServiceInstance nacosServiceInstance = (NacosServiceInstance) instanceMap.get(instance);
        if (StringUtils.isNotEmpty(NacosLoadBalancer.ipv6)) {
            convertIPv4ToIPv6(nacosServiceInstance);
        }
        return nacosServiceInstance;
    }

    /**
     * IPV4转IPV6
     *
     * @param instance 实例
     */
    private static void convertIPv4ToIPv6(NacosServiceInstance instance) {
        if (Pattern.matches(IPV4_REGEX, instance.getHost())) {
            String ip = instance.getMetadata().get(IPV6_KEY);
            if (StringUtils.isNotEmpty(ip)) {
                instance.setHost(ip);
            }
        }
    }

}
